package com.cencat.order.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cencat.order.dto.DriverDTO;
import com.cencat.order.entity.Driver;
import com.cencat.order.mapper.DriverMapper;
import com.cencat.order.service.DriverService;
import com.cencat.order.vo.DriverVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 司机业务逻辑实现类
 * 
 * @author cencat
 * @date 2024-01-20
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class DriverServiceImpl extends ServiceImpl<DriverMapper, Driver> implements DriverService {

    private final DriverMapper driverMapper;

    @Override
    public IPage<DriverVO> getDriverPage(Page<DriverVO> page, String driverName, String driverPhone,
                                        String licenseNumber, Integer driverStatus, Integer onlineStatus,
                                        Integer certificationStatus, LocalDateTime startTime, LocalDateTime endTime) {
        log.info("分页查询司机列表，参数：driverName={}, driverPhone={}, licenseNumber={}, driverStatus={}, onlineStatus={}, certificationStatus={}, startTime={}, endTime={}",
                driverName, driverPhone, licenseNumber, driverStatus, onlineStatus, certificationStatus, startTime, endTime);
        
        IPage<DriverVO> result = driverMapper.selectDriverPage(page, driverName, driverPhone, licenseNumber,
                driverStatus, onlineStatus, certificationStatus, startTime, endTime);
        
        log.info("分页查询司机列表完成，总数：{}", result.getTotal());
        return result;
    }

    @Override
    public DriverVO getByDriverCode(String driverCode) {
        log.info("根据司机编号查询司机信息，driverCode={}", driverCode);
        
        if (!StringUtils.hasText(driverCode)) {
            log.warn("司机编号不能为空");
            return null;
        }
        
        DriverVO result = driverMapper.selectByDriverCode(driverCode);
        log.info("根据司机编号查询司机信息完成，result={}", result != null ? "找到" : "未找到");
        return result;
    }

    @Override
    public List<DriverVO> getByStatus(Integer driverStatus, Integer onlineStatus, LocalDateTime startTime, LocalDateTime endTime) {
        log.info("根据状态查询司机列表，driverStatus={}, onlineStatus={}, startTime={}, endTime={}",
                driverStatus, onlineStatus, startTime, endTime);
        
        List<DriverVO> result = driverMapper.selectByStatus(driverStatus, onlineStatus, startTime, endTime);
        log.info("根据状态查询司机列表完成，数量：{}", result.size());
        return result;
    }

    @Override
    public List<DriverVO> getByLocation(BigDecimal longitude, BigDecimal latitude, BigDecimal radius,
                                       Integer driverStatus, Integer onlineStatus) {
        log.info("根据位置查询司机列表，longitude={}, latitude={}, radius={}, driverStatus={}, onlineStatus={}",
                longitude, latitude, radius, driverStatus, onlineStatus);
        
        if (longitude == null || latitude == null || radius == null) {
            log.warn("位置参数不能为空");
            return List.of();
        }
        
        List<DriverVO> result = driverMapper.selectByLocation(longitude, latitude, radius, driverStatus, onlineStatus);
        log.info("根据位置查询司机列表完成，数量：{}", result.size());
        return result;
    }

    @Override
    public List<DriverVO> getByCertificationStatus(Integer certificationStatus, LocalDateTime startTime, LocalDateTime endTime) {
        log.info("根据认证状态查询司机列表，certificationStatus={}, startTime={}, endTime={}",
                certificationStatus, startTime, endTime);
        
        List<DriverVO> result = driverMapper.selectByCertificationStatus(certificationStatus, startTime, endTime);
        log.info("根据认证状态查询司机列表完成，数量：{}", result.size());
        return result;
    }

    @Override
    public Map<String, Object> getDriverStatistics(Integer driverStatus, Integer onlineStatus,
                                                   Integer certificationStatus, LocalDateTime startTime, LocalDateTime endTime) {
        log.info("查询司机统计信息，driverStatus={}, onlineStatus={}, certificationStatus={}, startTime={}, endTime={}",
                driverStatus, onlineStatus, certificationStatus, startTime, endTime);
        
        Map<String, Object> result = driverMapper.selectDriverStatistics(driverStatus, onlineStatus,
                certificationStatus, startTime, endTime);
        
        log.info("查询司机统计信息完成");
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean createDriver(DriverDTO driverDTO) {
        log.info("创建司机信息，driverDTO={}", driverDTO);
        
        if (driverDTO == null) {
            log.warn("司机信息不能为空");
            return false;
        }
        
        // 检查司机编号是否已存在
        if (StringUtils.hasText(driverDTO.getDriverCode())) {
            DriverVO existingDriver = driverMapper.selectByDriverCode(driverDTO.getDriverCode());
            if (existingDriver != null) {
                log.warn("司机编号已存在：{}", driverDTO.getDriverCode());
                return false;
            }
        }
        
        Driver driver = new Driver();
        BeanUtils.copyProperties(driverDTO, driver);
        driver.setCreateTime(LocalDateTime.now());
        driver.setUpdateTime(LocalDateTime.now());
        driver.setDeleted(false);
        
        boolean result = save(driver);
        log.info("创建司机信息完成，result={}", result);
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateDriver(Long driverId, DriverDTO driverDTO) {
        log.info("更新司机信息，driverId={}, driverDTO={}", driverId, driverDTO);
        
        if (driverId == null || driverDTO == null) {
            log.warn("司机ID和司机信息不能为空");
            return false;
        }
        
        Driver existingDriver = getById(driverId);
        if (existingDriver == null) {
            log.warn("司机不存在：{}", driverId);
            return false;
        }
        
        Driver driver = new Driver();
        BeanUtils.copyProperties(driverDTO, driver);
        driver.setId(driverId);
        driver.setUpdateTime(LocalDateTime.now());
        
        boolean result = updateById(driver);
        log.info("更新司机信息完成，result={}", result);
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateDriverLocation(Long driverId, BigDecimal longitude, BigDecimal latitude, String locationAddress) {
        log.info("更新司机位置，driverId={}, longitude={}, latitude={}, locationAddress={}",
                driverId, longitude, latitude, locationAddress);
        
        if (driverId == null || longitude == null || latitude == null) {
            log.warn("司机ID和位置信息不能为空");
            return false;
        }
        
        boolean result = driverMapper.updateDriverLocation(driverId, longitude, latitude, locationAddress) > 0;
        log.info("更新司机位置完成，result={}", result);
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateDriverStatus(Long driverId, Integer driverStatus, String statusRemark) {
        log.info("更新司机状态，driverId={}, driverStatus={}, statusRemark={}", driverId, driverStatus, statusRemark);
        
        if (driverId == null || driverStatus == null) {
            log.warn("司机ID和状态不能为空");
            return false;
        }
        
        boolean result = driverMapper.updateDriverStatus(driverId, driverStatus, statusRemark) > 0;
        log.info("更新司机状态完成，result={}", result);
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateOnlineStatus(Long driverId, Integer onlineStatus, LocalDateTime onlineTime, LocalDateTime offlineTime) {
        log.info("更新司机在线状态，driverId={}, onlineStatus={}, onlineTime={}, offlineTime={}",
                driverId, onlineStatus, onlineTime, offlineTime);
        
        if (driverId == null || onlineStatus == null) {
            log.warn("司机ID和在线状态不能为空");
            return false;
        }
        
        boolean result = driverMapper.updateOnlineStatus(driverId, onlineStatus, onlineTime, offlineTime) > 0;
        log.info("更新司机在线状态完成，result={}", result);
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateCertificationStatus(Long driverId, Integer certificationStatus, String certificationRemark,
                                           LocalDateTime certificationTime, Long certifierId) {
        log.info("更新司机认证状态，driverId={}, certificationStatus={}, certificationRemark={}, certificationTime={}, certifierId={}",
                driverId, certificationStatus, certificationRemark, certificationTime, certifierId);
        
        if (driverId == null || certificationStatus == null) {
            log.warn("司机ID和认证状态不能为空");
            return false;
        }
        
        boolean result = driverMapper.updateCertificationStatus(driverId, certificationStatus, certificationRemark,
                certificationTime, certifierId) > 0;
        log.info("更新司机认证状态完成，result={}", result);
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchUpdateDriverStatus(List<Long> driverIds, Integer driverStatus) {
        log.info("批量更新司机状态，driverIds={}, driverStatus={}", driverIds, driverStatus);
        
        if (driverIds == null || driverIds.isEmpty() || driverStatus == null) {
            log.warn("司机ID列表和状态不能为空");
            return false;
        }
        
        boolean result = driverMapper.batchUpdateDriverStatus(driverIds, driverStatus) > 0;
        log.info("批量更新司机状态完成，result={}", result);
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean softDeleteDriver(Long driverId) {
        log.info("软删除司机信息，driverId={}", driverId);
        
        if (driverId == null) {
            log.warn("司机ID不能为空");
            return false;
        }
        
        Driver driver = new Driver();
        driver.setId(driverId);
        driver.setDeleted(true);
        driver.setUpdateTime(LocalDateTime.now());
        
        boolean result = updateById(driver);
        log.info("软删除司机信息完成，result={}", result);
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchSoftDeleteDrivers(List<Long> driverIds) {
        log.info("批量软删除司机信息，driverIds={}", driverIds);
        
        if (driverIds == null || driverIds.isEmpty()) {
            log.warn("司机ID列表不能为空");
            return false;
        }
        
        List<Driver> drivers = driverIds.stream()
                .map(id -> {
                    Driver driver = new Driver();
                    driver.setId(id);
                    driver.setDeleted(true);
                    driver.setUpdateTime(LocalDateTime.now());
                    return driver;
                })
                .collect(Collectors.toList());
        
        boolean result = updateBatchById(drivers);
        log.info("批量软删除司机信息完成，result={}", result);
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean restoreDriver(Long driverId) {
        log.info("恢复已删除的司机信息，driverId={}", driverId);
        
        if (driverId == null) {
            log.warn("司机ID不能为空");
            return false;
        }
        
        Driver driver = new Driver();
        driver.setId(driverId);
        driver.setDeleted(false);
        driver.setUpdateTime(LocalDateTime.now());
        
        boolean result = updateById(driver);
        log.info("恢复已删除的司机信息完成，result={}", result);
        return result;
    }

    @Override
    public List<Map<String, Object>> getDriverLoginLogs(Long driverId, LocalDateTime startTime, LocalDateTime endTime, Integer limit) {
        log.info("查询司机登录日志，driverId={}, startTime={}, endTime={}, limit={}",
                driverId, startTime, endTime, limit);
        
        if (driverId == null) {
            log.warn("司机ID不能为空");
            return List.of();
        }
        
        List<Map<String, Object>> result = driverMapper.selectDriverLoginLogs(driverId, startTime, endTime, limit);
        log.info("查询司机登录日志完成，数量：{}", result.size());
        return result;
    }
}